RunTime复习 | iOS
【记录下那些看似没用的知识点】
- RunTime复习
- 今天圣诞节公司聚会到了晚上11点刚回到寝室,泡脚的时候(没事多泡脚是有好处的)才发现今天还有任务没完成 - 记录下今天对于RunTime的知识点复习
【主要内容】
一. 简介
首先用我自己的语言描述下什么是runtime 通俗易懂的:oc代码在编译期间其实是不知道要调用那个函数的,只有在运行之后才会根据函数名查找对应的函数(就好比新生上学的时候,老师已经拿到学生名单表了,但是不知道这个名字对应的是谁,只有在正式开始上课的时候才知道这个名字对应哪个人),这样的一个机制就叫做RunTime(运行时)
- 下面是网上普遍对如runtime的一个简介
因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时。也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的代码。这就是 Objective-C Runtime 系统存在的意义,它是整个Objc运行框架的一块基石。
RunTime简称运行时。OC就是运行时机制,其中最主要的是消息机制。对于C语言,函数的调用在编译的时候会决定调用哪个函数。对于OC的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。
Runtime基本是用C和汇编写的,可见苹果为了动态系统的高效而作出的努力。你可以在这里下到苹果维护的开源代码。苹果和GNU各自维护一个开源的runtime版本,这两个版本之间都在努力的保持一致。
二. 作用
1.消息发送
- 使用方法调用的本质其实就是让对象发送消息
- objc_msgSend ,只有对象才能发送消息
简单的例子:(先导入#import <objc/message.h>)(+-两个符号代表对象的类方法和实例方法)
创建person对象
MyClass *p = [[MyClass alloc] init];
调用对象方法
[p eat];
本质:让对象发送消息
objc_msgSend(p, @selector(eat));
调用类方法的方式:两种
(1)第一种通过类名调用
[MyClass eat];
(2)第二种通过类对象调用
[[Person class] eat];
用类名调用类方法,底层会自动把类名转换成类对象调用
本质:让类对象发送消息
objc_msgSend([Person class], @selector(eat));
2.交换方法
- 当系统自带的方法功能不够,不全,在给系统自带的方法扩展一些功能,并同时保持原有的功能。
- 1.继承系统的类,重写方法.
- 2.使用runtime,交换方法.
例子:(简单吧)
加载分类到内存的时候调用
+(void) load {
Method imageWithName = class_getClassMethod(self, @selector(imageWithName:));
Method imageName = class_getClassMethod(self, @selector(imageNamed:));
method_exchangeImplementations(imageWithName, imageName);
}
3.动态添加方法
- 如果一个类方法非常多,加载类到内存的时候也比较耗费资源,需要给每个方法生成映射表,可以使用动态给某个类,添加方法解决。
例子:(简单吧)
@implementation ViewController
-(void)viewDidLoad {
[super viewDidLoad];
Person *p = [[Person alloc] init];
[p performSelector:@selector(eat)];
}
@end
@implementation Person
void eat(id self,SEL sel)
{
NSLog(@”%@ %@”,self,NSStringFromSelector(sel));
}
+(BOOL)resolveInstanceMethod:(SEL)sel{
if (sel == @selector(eat)) {
class_addMethod(self, @selector(eat), eat, “v@:”);
}
return [super resolveInstanceMethod:sel];
}
@end
【其他】
还有添加分类 ,字典转换模型 找时间添加上去,睡觉······